package me.ezitku.JsBridge.Handler

import android.os.Build
import android.support.annotation.RequiresApi
import android.webkit.WebView
import com.example.yurqi.webviewexample.model.Person
import com.google.gson.Gson
import me.ezitku.JsBridge.Utils.GsonUtil
import java.lang.reflect.InvocationHandler
import java.lang.reflect.Method
import java.lang.reflect.ParameterizedType
import kotlin.jvm.internal.FunctionBase

@Suppress("UNCHECKED_CAST")
class JsBridgeInvocationHandler(var webView: WebView) : InvocationHandler {

    var returnTypeIslist = false
    var returnType: Class<*>? = null
    lateinit var genericType: Class<*>
    @RequiresApi(Build.VERSION_CODES.KITKAT)
    override fun invoke(proxy: Any?, method: Method, args: Array<out Any>?): Any? {
        var url = "javascript:${method.name}("
        var callBack: (Any) -> Unit = {}

        if (args != null && args.isNotEmpty()) {
            args.forEach {
                if (it !is FunctionBase) {
                    if (it.javaClass.isPrimitive) {
                        when (it) {
                            is String -> {
                                url += "\"$it\""
                            }
                            else -> {
                                url += it
                            }
                        }
                    } else {
                        url += Gson().toJson(it)
                    }
                    url += ","
                } else if (it is FunctionBase) {
                    callBack = args.last() as (Any) -> Unit
                    returnType = method.returnType
                    if (returnType != null) {
                        if (returnType!!.isPrimitive) {
                            returnType = method.returnType
                            returnTypeIslist = false
                        } else {
                            if (method.returnType.isAssignableFrom(List::class.java)) {
                                returnTypeIslist = true
                                var generic = method.genericReturnType
                                if (generic is ParameterizedType) {
                                    var pt = generic as ParameterizedType
                                    var type = pt.actualTypeArguments[0]
                                    genericType = type.javaClass
                                }
                                print(returnType)
                                print(generic)

                            }
                        }

                    }

                }
            }
        }
        if (url.endsWith(",")) {
            url = url.substring(0, url.length - 1)
        }
        url += ")"

        webView.evaluateJavascript(url)
        { result ->
            if (returnTypeIslist) {
//                var retv = GsonUtil.parseJsonArrayWithGson(result, Person::class.java)
                var retv = GsonUtil.getListFromJSON(result, Array<Person>::class.java)
                callBack.invoke(retv.toList())
            } else {
                if (returnType != null) {
                    var retv = GsonUtil.parseJsonWithGson(result, returnType)
                    callBack.invoke(retv)
                }
            }
            //callBack.invoke(result)
            returnTypeIslist = false
            returnType = null
        }

        var tt = method.genericParameterTypes
        var tt1 = method.genericExceptionTypes
        print(tt)
        print(tt1)
        return null

    }
}


